package com.cc.pokergame.model;

import android.net.Uri;
import android.view.View;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.cc.pokergame.R;
import com.cc.pokergame.utils.AnimatorUtils;

import java.io.File;

/**
 * 玩家类
 */
public class Player {
    private PlayerState state = PlayerState.IDLE; // 玩家状态
    private int avatarId; // 玩家头像资源
    private String avatarFilePath; // 玩家头像资源
    private String name; // 玩家名字
    private int money; // 金额
    private Poker playerPoker; // 玩家到手的牌
    private View mView; // 玩家信息视图
    private View breathView;        //呼吸灯视图
    private ImageView avatarView;     //头像视图
    private ImageView arrowView; // 箭头视图
    private TextView moneyView; // 金额视图
    private TextView nameView; // 名字视图
    private ImageView playerPokerView; // 玩家得到牌的视图
    private ImageView pokerWinnerView; // 玩家当前牌赢的视图

    /**
     * 创建玩家时，初始化玩家的基本信息
     *
     * @param avatarId 玩家头像资源id
     * @param name     玩家名字
     * @param money    玩家金额
     */
    public Player(int avatarId, String name, int money) {
        this.avatarId = avatarId;
        this.name = name;
        this.money = money;
    }

    /**
     * 创建玩家时，初始化玩家的基本信息
     *
     * @param path  玩家头像文件路径
     * @param name  玩家名字
     * @param money 玩家金额
     */
    public Player(String path, String name, int money) {
        this.avatarFilePath = path;
        this.name = name;
        this.money = money;
    }

    /**
     * 下注金额
     *
     * @param money 当前桌默认下注金额
     * @return 返回减去金币的值
     */
    public int deductTableMonet(int money) {
        // 声明减去金币的值
        int countMoney = 0;
        if (this.money >= money) {
            this.money -= money;
            countMoney = money; // 将减去的金币交给
        } else {
            // 当玩家金额处于不足时
            countMoney = this.money;
            this.money = 0;
        }
        moneyView.setText(this.money + "");
        // 返回减去金币的值
        return countMoney;
    }

    /**
     * 判断是否为弃牌状态
     *
     * @return
     */
    public boolean isGiveUp() {
        return state == PlayerState.GIVE_UP;
    }

    /**
     * 判断是否为活跃状态
     *
     * @return
     */
    public boolean isActive() {
        return state != PlayerState.GIVE_UP;
    }

    /**
     * 实现赢的玩家 加钱功能
     *
     * @param totalMoney
     */
    public void addMoney(int totalMoney) {
        money += totalMoney;

        moneyView.setText(money + "");

        // 赢家的牌有获胜图标
        AnimatorUtils.alphaIn(this.pokerWinnerView);
    }

    /**
     * 显示扑克
     */
    public void showPoker() {
        playerPoker.changeToFrontState();
        flipCard();
    }

    public void flipCard() {
        AnimatorUtils.rotateY(playerPokerView, 0f, 90f);
        this.playerPokerView.setImageResource(this.playerPoker.getPokerRes());
        AnimatorUtils.rotateY(playerPokerView, 270f, 360f);
    }

    /**
     * 设置玩家拿到的牌，并且设置玩家的牌资源
     *
     * @param playerPoker 一张牌
     */
    public void setPlayerPoker(Poker playerPoker) {
        this.playerPoker = playerPoker;

        // 在设置完玩家牌时，显示玩家的牌
        this.playerPokerView.setImageResource(playerPoker.getPokerRes());
    }

    /**
     * 绑定玩家拿到牌的视图
     *
     * @param pokerView 牌的视图
     */
    public void bindPokerView(CardModel pokerView) {
        this.playerPokerView = pokerView.getPokerView();
        this.pokerWinnerView = pokerView.getWinnerView();

        // 监听点击事件
        this.playerPokerView.setOnClickListener(v -> {
            // 修改扑克的状态
            this.playerPoker.changePokerState();

            AnimatorUtils.rotateY(pokerView.getPokerView(), 0f, 90f);
            this.playerPokerView.setImageResource(playerPoker.getPokerRes());
            AnimatorUtils.rotateY(pokerView.getPokerView(), 270f, 360f);
        });
    }

    /**
     * 绑定视图
     *
     * @param view 玩家视图
     */
    public void bindView(View view) {
        this.mView = view;

        breathView = mView.findViewById(R.id.breathView);
        avatarView = mView.findViewById(R.id.avatar);
        arrowView = mView.findViewById(R.id.arrowhead);
        moneyView = mView.findViewById(R.id.money);
        nameView = mView.findViewById(R.id.playerName);

        bindData();
    }

    /**
     * 绑定数据
     */
    private void bindData() {
        if (state == PlayerState.IDLE || state == PlayerState.GIVE_UP) {
            breathView.setBackgroundResource(R.drawable.head_normal_circle_shape);
            arrowView.setImageResource(R.drawable.arrow_gray);
            cancelAvatarAnimation();
        } else {
            breathView.setBackgroundResource(R.drawable.head_active_circle_shape);
            arrowView.setImageResource(R.drawable.arrow_green);
            AnimatorUtils.scaleInOut(avatarView, 1f, 0.95f);
        }

        if (this.avatarFilePath != null) {
            avatarView.setImageURI(avatarUri());
            Glide.with(avatarView.getContext())
                    .load(avatarUri())
                    .apply(RequestOptions.circleCropTransform())
                    .into(avatarView);
        } else {
            avatarView.setImageResource(avatarId);
        }

        nameView.setText(name);
        moneyView.setText(money + "");
    }

    /**
     * 修改玩家状态
     *
     * @param playerState 设置玩家的状态
     */
    public void changePlayerState(PlayerState playerState) {
        this.state = playerState;
        bindData();
    }

    /**
     * 关闭头像呼吸灯效果
     */
    public void cancelAvatarAnimation() {
        // 用头像视图获取到当前动画对象
        ScaleAnimation animation = (ScaleAnimation) avatarView.getAnimation();
        if (animation != null) {
            // 关闭动画
            animation.cancel();
        }
    }

    @NonNull
    @Override
    public String toString() {
        return name + "-" + playerPoker.toString();
    }

    /**
     * 重置牌的状态
     */
    public void resetPokerState() {
        // 隐藏winner图标
        AnimatorUtils.alphaOut(pokerWinnerView);
        if (playerPoker != null) {
            // 修改牌的状态
            playerPoker.changePokerState();
            // 翻牌
            flipCard();
        }

    }

    /**
     * 玩家的牌进行pk
     *
     * @param nextPlayer 下一个玩家对象
     * @return 返回玩家的牌pk结果
     */
    public int pk(Player nextPlayer) {
        // 在牌对象中比较牌的大小，返回比较结果
        return playerPoker.compareTo(nextPlayer.playerPoker);
    }

    public Uri avatarUri() {
        File file = new File(this.avatarFilePath);
        return Uri.fromFile(file);
    }

    public int getMoney() {
        return money;
    }

    public String getName() {
        return name;
    }

    /**
     * 玩家状态
     */
    public enum PlayerState {
        IDLE, // 空闲状态
        ACTIVE, // 活跃状态
        GIVE_UP, // 弃牌
    }
}


